#include "Common.h"
#include "pipe.hpp"
#include <iostream>
#include <unistd.h> // sleep
#include <cstdio>
#include <sys/shm.h> //shmget shmctl
#include <sys/ipc.h>
#include <cstring> //memcpy

#define PATH "."
#define PERMISSION 0666

#define ROOT IPC_CREAT | IPC_EXCL | PERMISSION
#define USER IPC_CREAT

class Shm
{
private:
    
    void GetMemo()
    {
        _key = ftok(PATH, 8);
        int ret = shmget(_key, 4096, _mode);
        if (ret < 0)
        {
            ERR_EXIT("shmget");
        }
        _shmid = ret;
    }
    void DeleteMemo()
    {
        int ret = shmctl(_key, IPC_RMID, nullptr);
        if (ret > 0)
        {
            printf("shared memory destoryed , key = %d", _key);
        }
        else
        {
            ERR_EXIT("shmctl");
        }
    }
    void Attach()
    {
        char *ad = (char *)shmat(_shmid, nullptr, 0);
        if ((long long)ad < 0)
        {
            ERR_EXIT("shmat");
        }
        _address = ad;
        std::cout << "attach success!!\n";
    }
    void Detach()
    {
        int ret = shmdt(_address);
        if(0 == ret)
            printf("detach success\n");
    }
    void Destory()
    {
        if(_address)
        {
            Detach();
            DeleteMemo();
        }

    }
    void State() //get information
    {
        shmid_ds content;
        int ret = shmctl(_shmid,IPC_STAT,&content);
        std::cout << "content.shm_cpid" << content.shm_cpid << std::endl;
        std::cout << "content.shm_nattch" << content.shm_nattch << std::endl;
        //std::cout << "content.shm_perm" << content.shm_perm << std::endl;
        std::cout << "content.shm_segsz" << content.shm_segsz << std::endl;

    }
public:
    Shm( int mode = ROOT)
    :_mode(mode)
    {
        GetMemo();
        Attach();
    }
    void* Address()
    {
        return _address;
    }
    ~Shm()
    {
        Destory();
    }
private:
    key_t _key;
    int _shmid;
    void* _address = nullptr;
    int _mode;
};